package field

// 在此处定义帧字段及处理处理方法
import (
	"bytes"
	"encoding/binary"
	"fmt"

	"gitee.com/yanwc/ebicycle/device/utils"
)

// 头字段
type (
	SerialNumber  [1]byte // 序列号
	CommandWord   [1]byte // 命令字
	ContentLength [2]byte // 内容长度
)

// 状态和告警字段
type (
	FirmwareVersion [4]byte  // 固件版本
	IMEI            [15]byte // Imei
	IMSI            [15]byte // imsi
	DeviceType      [1]byte  // 设备类型
	CSQ             [1]byte  // 设备的GSM 信号强度，取值范围[0,31]
	Voltage         [1]byte  // 设备实时电压，单位：伏
	WarnType        [1]byte  // 告警类型
)

// 状态及tlv字段
type (
	SW                [4]byte // BIT位开关
	GSM               [1]byte // GSM信号强度(0-31)
	VoltageMV         [4]byte // 电池电压，单位：mV
	LocationTimestamp [4]byte // 定位时间戳 单位: s
	Longitude         [4]byte // 经度 WGS84坐标系, 单位:0.000001°
	Latitude          [4]byte // 纬度 WGS84坐标系, 单位:0.000001°
	Altitude          [4]byte // 海拔高度 WGS84坐标系, 单位:米  int32 有符号
	Speed             [2]byte // 速度 单位: 0.1km/h
	Course            [2]byte // 方向(相对正北方向) 单位: °
	Hdop              [2]byte // 水平精度因子(0-9999) 单位:0.01
	Satellite         [1]byte // 可用卫星数量(3-24)
	TotalMiles        [4]byte // 设备当前累计总里程 单位:米
	FenceVersion      [4]byte // 设备内置围栏版本号
)


const (
	OutDistrictWarn        byte = 0x01 // 出服务围栏告警
	InDistrictWarn         byte = 0x02 // 入服务围栏告警
	MoveWarn               byte = 0x03 // 非法移动告警
	LowBatteryWarn         byte = 0x04 // 低电压通知，低于50%告警一次
	CriticalLowBatteryWarn byte = 0x05 // 严重低电压告警，低于30%告警一次
	AutoLockNotify         byte = 0x13 // 自动落锁通知
	SideDownNotify         byte = 0x27 // 倾倒事件通知
	RecoverSideDownNotify  byte = 0x28 // 倾倒恢复通知
	OutAlertFenceNotify    byte = 0x32 // 出告警围栏通知
	InAlertFenceNotify     byte = 0x33 // 入告警围栏通知
	DragBikeWarn           byte = 0x52 // 拖车告警
)

// Major.Minor.Patch.XXX
func (v *FirmwareVersion) String() string {
	var major uint8
	var minor uint8
	var patch uint8
	var xxx uint8
	binary.Read(bytes.NewBuffer(v[0:1]), binary.BigEndian, &major)
	binary.Read(bytes.NewBuffer(v[1:2]), binary.BigEndian, &minor)
	binary.Read(bytes.NewBuffer(v[2:3]), binary.BigEndian, &patch)
	binary.Read(bytes.NewBuffer(v[3:4]), binary.BigEndian, &xxx)
	return fmt.Sprintf("%d.%d.%d.%d", major, minor, patch, xxx)
}

func (i *IMEI) String() string {
	return utils.BytesToString(i[:])
}

func (i *IMSI) String() string {
	return utils.BytesToString(i[:])
}

func (dt *DeviceType) Uint8() (v uint8) {
	binary.Read(bytes.NewBuffer(dt[:]), binary.BigEndian, &v)
	return
}

func (cw *CommandWord) Uint8() (v uint8) {
	binary.Read(bytes.NewBuffer(cw[:]), binary.BigEndian, &v)
	return
}

func (csq *CSQ) Uint8() (v uint8) {
	binary.Read(bytes.NewBuffer(csq[:]), binary.BigEndian, &v)
	return
}

func (vol *Voltage) Uint8() (v uint8) {
	binary.Read(bytes.NewBuffer(vol[:]), binary.BigEndian, &v)
	return
}

func (wt *WarnType) Uint8() (v uint8) {
	binary.Read(bytes.NewBuffer(wt[:]), binary.BigEndian, &v)
	return
}

func (tt *TLVType) Uint8() (v uint8) {
	binary.Read(bytes.NewBuffer(tt[:]), binary.BigEndian, &v)
	return
}

func (tl *TLVLen) Uint8() (v uint8) {
	binary.Read(bytes.NewBuffer(tl[:]), binary.BigEndian, &v)
	return
}
